#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <stdbool.h>

#define sin(x) _Generic(x, \
                        float:sinf, \
                        double:sin, \
                        long double:sinl,   \
                        float _Complex : csinf, \
                        double _Complex : csin, \
                        long double _Complex : csinl) (x)

int square(int);
int fact(int n);
int check(int, int, int);
int gcd(int, int);
void example4(int, int, int);
void example5(int);
void example6(int, int);
int example7(int, int);
void example11(const char[], int);
void example12(const double a[], const double b[], int n);
void fact_non_recursive(int n);
int gcd_recursive(int m, int n);
void pb(int n);

int main(void) {

    printf("pb function start-----------------\n");
    pb(4);
    printf("pb function end-----------------\n");
    printf("gcd_recursive is %d\n", gcd_recursive(10, 2));
    fact_non_recursive(10);
    double arr_b[] = {5, 4, 3, 2, 1};
    example12(
            (double[]) {1, 2, 3, 4, 5},
            arr_b,
            5
            );
    example11((char[]){'A', 'B', 'c', 'd', 'F'}, 5);
    double x1;
    x1 = example7(83.5, 12.3);
    example6(382, 1);
    example5(3483942);
    example4(1, 14, 2025);
    gcd(10 ,2);
    printf("%d\n", check(1, 2, 3));

    // .5f 就是0.5 下面的.3就是0.3
    printf("%f\n", sin(.5f));

    double _Complex d = sin(.3 + .5i);
    printf("%.2f%+.2f*I", creal(d), cimag(d));

    double x = 3.0;
    printf("Square: %d\n", square(x));

    return 0;
}
// 将int转换为一个二进制
void pb(int n) {
    if(n != 0) {
        pb(n / 2);
        // 1是49,2是50，以此类推，最终以字符串的形式输出
        putchar('0' + n % 2);
    }
}

bool has_zero(const int a[], int n) {
    int i;
    for (i = 0; i < n; ++i)
        if (a[i] == 0)
            return true;
        else
            return false;
    // 14 题中的问题：没有下面这行
    return false;
}

void evaluate_position(char board[8][8]) {
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 8; ++j) {
            char cur = board[i][j];
            int whiteNum = 0;
            int blackNum = 0;
            switch (cur) {
                case 'Q':
                    whiteNum += 9;
                    break;
                case 'R':
                    whiteNum += 5;
                    break;
                case 'B':
                    whiteNum += 3;
                    break;
                case 'N':
                    whiteNum += 3;
                    break;
                case 'P':
                    whiteNum += 1;
                    break;
                case 'k':
                    break;
                case 'q':
                    whiteNum += 9;
                    break;
                case 'r':
                    whiteNum += 9;
                    break;
                case 'b':
                    whiteNum += 9;
                    break;
                case 'n':
                    whiteNum += 9;
                    break;

            }
        }
    }
}

void example12(const double a[], const double b[], int n) {
    printf("example12 start----------------\n");
    double num = 0;
    for (int i = 0; i < n; ++i) {
        num += a[i] + b[i];
    }
    printf("example12 result is %g\n", num);
    printf("example12 end----------------\n");
}

void example11(const char grades[], int n) {
    printf("example11 start----------------\n");
    int num = 0;
    for (int i = 0; i < n; ++i) {
        char cur = grades[i];

        switch (cur) {
            case 'a':
            case 'A':
                num += 4;
                break;
            case 'b':
            case 'B':
                num += 3;
                break;
            case 'c':
            case 'C':
                num += 2;
                break;
            case 'd':
            case 'D':
                num += 1;
                break;
            case 'f':
            case 'F':
                num += 0;
                break;
        }
    }
    int arvage = num / n;
    printf("arivage is %d\n", arvage);
    printf("example11 start----------------\n");
}

int example7(int a, int b) {
    return a+b;
}

void example6(int n, int k) {
    printf("example6 start----------------\n");
    int count = 0;
    int n1 = n;
    int cur_digit;
    do {
        cur_digit = n1 % 10;
        n1 /= 10;
        count++;
        if(k == count) {
            printf("The number has k digit and is equal to %d.\n", cur_digit);
            return;
        }
    } while  (n1 != 0);
    printf("The number has k digit and is equal to %d.(large)\n", 0);
    printf("example6 end----------------\n");
}

void example5(int n) {
    printf("example5 start----------------\n");
    int count = 0;
    int n1 = n;
    do {
        n1 /= 10;
        count++;
    } while  (n1 != 0);
    printf("number %d has %d digit.\n", n, count);
    printf("example5 end----------------\n");
}

void example4(int month, int day, int year) {
    printf("example4 start----------------\n");
    int day_count = 0;
    int num_days[] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    for (int i = 1; i < month; ++i) {
        day_count += num_days[i];
    }

    if (year % 4 == 0 && month > 2) {
        day_count++;
    }

    day_count += day;
    printf("day of year is %d\n", day_count);
    printf("example4 end----------------\n");
}


int gcd(int m, int n) {
    printf("example3 start----------------\n");
    int temp;
    while(n != 0) {
        temp = m % n;
        m = n;
        n = temp;
    }
    printf("euclid is %d\n", m);
    printf("example3 end----------------\n");
    return m;
}

int gcd_recursive(int m, int n) {
    if (n == 0) {
        return m;
    }
    return gcd_recursive(n, m % n);
}

int check(int x, int y, int n) {
    if (x >= 0 && x <= n - 1 && y >= 0 && y <= n - 1) {
        return 1;
    }
    return 0;
}

int square(int n) {
    return n * n;
}

int fact(int n) {
    if (n <= 1)
        return 1;
    else
        return n * fact(n - 1);
}

void fact_non_recursive(int n) {
    int res = 1;
    if (n == 0) {
        printf("fact_non_recursive %d is %d\n", n, 0);
        printf("example3 end----------------\n");
        return;
    }
    for (int i = 1; i <= n; ++i) {
        res *= i;
    }

    printf("fact_non_recursive %d is %d\n", n, res);
    printf("fact is %d\n", fact(n));
    printf("example3 end----------------\n");
}